﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MacomberMapSystem.Common.Errors
{/// <summary>
    /// This class holds information on a message to be displayed to the user
    /// </summary>
    public class MM_Event : Exception
    {
        #region Variable declarations          
        /// <summary>
        /// This class holds information on an exception type
        /// </summary>
        public enum enumExceptionType
        {
            /// <summary>Information to displayed</summary>
            Information,
            ///<summary>Warning information</summary>
            Warning,
            ///<summary>Error information</summary>
            Error
        }

        /// <summary>The exception type</summary>        
        public enumExceptionType ExceptionType = enumExceptionType.Error;

        /// <summary>
        /// The delegate for handling an MM event
        /// </summary>
        /// <param name="Event">The event that occurred</param>
        public delegate void MM_Event_Delegate(MM_Event Event);
        
        /// <summary>The error handlers for events</summary>
        public static event MM_Event_Delegate EventOccurred;
        #endregion

        #region Initialization
        /// <summary>
        /// Log a message to the event queue
        /// </summary>
        /// <param name="Message">The message to be logged</param>
        /// <param name="Parameters">The parameters for the message</param>
        /// <param name="ExceptionType">The exception type</param>
        public static void LogMessage(String Message, enumExceptionType ExceptionType, params object[] Parameters)
        {
            MM_Event NewEx = new MM_Event(String.Format(Message, Parameters), ExceptionType);
            if (EventOccurred == null)            
                Console.WriteLine(ExceptionType.ToString() + ": " + NewEx.Message);
            else
                EventOccurred(NewEx);                        
        }

        /// <summary>
        /// Log an error with inner exception
        /// </summary>
        /// <param name="Message"></param>
        /// <param name="ex"></param>
        /// <param name="Parameters"></param>
        public static void LogError(String Message, Exception ex, params object[] Parameters)
        {
            MM_Event NewEx = new MM_Event(String.Format(Message, Parameters), ex);
            if (EventOccurred == null)
                Console.WriteLine("Error: " + NewEx.Message);
            else
                EventOccurred(NewEx);            
        }

        /// <summary>
        /// Log an error to the queue
        /// </summary>
        /// <param name="ex"></param>
        public static void LogError(Exception ex)
        {
            MM_Event NewEx = new MM_Event(ex);
            if (EventOccurred == null)
                Console.WriteLine("Error: " + NewEx.Message);
            else
                EventOccurred(NewEx);
        }

        /// <summary>
        /// Initialize a new exception
        /// </summary>
        /// <param name="Message">The message to display</param>
        /// <param name="ex"></param>
        private MM_Event(String Message, Exception ex)
            : base(Message, ex)
        {
            this.ExceptionType = enumExceptionType.Error;
        }


        /// <summary>
        /// Initialize a new exception
        /// </summary>
        /// <param name="Message"></param>
        /// <param name="ExceptionType"></param>
        private MM_Event(String Message, enumExceptionType ExceptionType)
            : base(Message)
        {
            this.ExceptionType = ExceptionType;
        }

        /// <summary>
        /// Initialize a new exception        
        /// </summary>
        /// <param name="ex"></param>
        private MM_Event(Exception ex)
            : base(ex.Message, ex)
        {
            this.ExceptionType = enumExceptionType.Error;
        }
        #endregion


        /// <summary>
        /// Report this message as a string
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            Exception InnerEx = this;
            while (this.InnerException != null)
                InnerEx = InnerEx.InnerException;
            if (this == InnerEx)
                return Message;
            else
                return Message + " (" + InnerEx.Message + ")";
        }
    }
}
